
package com.studiofortress.sf.util;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;

/**
 * This is a fully static class offering some methods to find resources. It
 * simplifies the code for the user and aims to fix a few common mistakes a user
 * may perform.
 *
 * When using getURL and getStream the resource name will be altered to search
 * both relative and absolute paths for the resource. For example if searching
 * for 'music/game.ogg', if it is not found then it will search again as
 * '/music/game.ogg'.
 *
 * The getURLExplicit and getStreamExplicit do not alter the path when
 * searching.
 *
 * @author Joseph Lenton - JL235@Kent.ac.uk
 */
public final class Resource
{
    /**
     * No constructor, this is a fully static class.
     */
    private Resource() { }

    public static URL getURL(final String name)
    {
        URL url = getURLExplicit(name);

        if (url != null) {
            return url;
        } else {
            return getURLExplicit(relativeAbsoluteSwitch(name));
        }
    }

    public static URL getURLExplicit(final String name)
    {
        return Resource.class.getResource(name);
    }

    public static InputStream getStream(final String name)
    {
        InputStream stream = getStreamExplicit(name);

        if (stream != null) {
            return stream;
        } else {
            stream = getStreamExplicit(relativeAbsoluteSwitch(name));
            if ( stream != null ) {
                return stream;
            } else {
                try {
                    return new File( name ).toURI().toURL().openStream();
                } catch (IOException e) {
                    throw new RuntimeException( e );
                }
            }
        }
    }

    public static InputStream getStreamExplicit(final String name)
    {
        return Resource.class.getResourceAsStream(name);
    }

    /**
     * Alters the given name of a resource between absolute and relative name.
     * For example if '/music/foo.mp3' is given then 'music/foo.mp3' is
     * returned, and vise versa.
     * @param name
     * @return
     */
    private static String relativeAbsoluteSwitch(final String name)
    {
        if (name.startsWith("/")) {
            return StringUtil.trimLeft(name, '/');
        } else {
            return "/" + name;
        }
    }
}
